﻿using System;
using System.Collections.Generic;
using System.Text;
using CarbonExchange.AmeeQuery;
using CarbonExchange.Dal;
using System.Linq;

namespace CarbonExchange.Bll
{
    public class QuestionTextFactory : FactoryBase<QuestionText>
    {
        public QuestionTextFactory() : base() { }

        public QuestionTextFactory(IAmeeCommand ameeCommand) : base(ameeCommand) { }

        public QuestionTextFactory(Context dalContext) : base(dalContext) { }

        public QuestionTextFactory(IAmeeCommand ameeCommand, Context dalContext) : base(ameeCommand, dalContext) { }

        protected override void MarkItemForDeletion(QuestionText item)
        {
            if (item != null && item.Id > 0)
            {
                var tmp = DalContext.QuestionTexts.Where(x => x.Id == item.Id && !x.Deleted).Single();
                tmp.Deleted = true;
            }
        }

        protected override void Validate(IQueryable<QuestionText> items, CarbonExchange.Bll.Exceptions.ValidationException exp)
        {
            items.Validate(exp, DalContext);
        }

        protected override void PopulateDataChanges(QuestionText item, object dataItem)
        {
            var tmp = dataItem as Dal.QuestionText;
            if (tmp != null)
            {
                if (item.Id == 0)
                {
                    item.Id = tmp.Id;
                }
                item.CID = tmp.CID;
            }
        }

        protected override object GetDataItemForUpdate(QuestionText item)
        {
            return item.Convert(DalContext);
        }

        private IQueryable<Dal.QuestionText> GetSelection()
        {
            return DalContext.QuestionTexts.Where(x => !x.Deleted);
        }

        public IQueryable<QuestionText> GetAllByQuestionId(int questionId, int siteId)
        {
            return GetSelection().Where(x => x.QuestionId == questionId && x.SiteId == siteId).OrderBy(x => x.Name).Convert();
        }

        public QuestionText GetById(int id)
        {
            return GetSelection().Where(x => x.Id == id).OrderBy(x => x.Name).SingleOrDefault().Convert();
        }

        public QuestionText GetByQuestionIdAndName(int questionId, int siteId, string name)
        {
            return GetSelection().Where(x => x.QuestionId == questionId && x.SiteId == siteId && x.Name == name).SingleOrDefault().Convert();
        }
    }

    internal static class QuestionTextConverter
    {
        internal static QuestionText Convert(this Dal.QuestionText source)
        {
            return ConvertItem(source);
        }

        internal static IQueryable<QuestionText> Convert(this IQueryable<Dal.QuestionText> source)
        {
            return source.Select(x => ConvertItem(x));
        }

        private static QuestionText ConvertItem(Dal.QuestionText item)
        {
            if (item != null)
            {
                return new QuestionText()
                {
                    Id = item.Id,
                    CID = item.CID,
                    Name = item.Name,
                    QuestionId = item.QuestionId,
                    SiteId = item.SiteId, 
                    Text = item.Text,
                    Created = item.Created.ToServerTime()
                };
            }
            else
            {
                return null;
            }
        }

        internal static Dal.QuestionText Convert(this QuestionText source, Dal.Context context)
        {
            return ConvertItem(source, context);
        }

        internal static IQueryable<Dal.QuestionText> Convert(this IQueryable<QuestionText> source, Dal.Context context)
        {
            return source.Select(x => ConvertItem(x, context));
        }

        private static Dal.QuestionText ConvertItem(QuestionText item, Dal.Context context)
        {
            if (item != null)
            {
                Dal.QuestionText tmp = null;
                if (item.Id > 0)
                {
                    tmp = context.QuestionTexts.Where(x => !x.Deleted && x.Id == item.Id).Single();
                }
                else
                {
                    tmp = context.QuestionTexts.Where(x => !x.Deleted && x.QuestionId == item.QuestionId && x.SiteId == item.SiteId && x.Name == item.Name).SingleOrDefault();
                    if (tmp == null)
                    {
                        tmp = new CarbonExchange.Dal.QuestionText();
                        tmp.Name = item.Name;
                        tmp.QuestionId = item.QuestionId;
                        tmp.SiteId = item.SiteId;
                        tmp.Created = DateTime.UtcNow;
                        item.Created = tmp.Created.ToLocalTime();
                        context.QuestionTexts.InsertOnSubmit(tmp);
                    }
                }
                item.EnsureConcurent(tmp.CID);
                tmp.Text = item.Text;
                return tmp;
            }
            else
            {
                return null;
            }
        }

        public static void Validate(this IQueryable<QuestionText> source, Bll.Exceptions.ValidationException e, Dal.Context context)
        {
            foreach(var item in source)
            {
                item.Validate(e, context);
            }
        }

        public static void Validate(this QuestionText source, Bll.Exceptions.ValidationException e, Dal.Context context)
        {
        }
    }
}
